﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Expression.Encoder.Profiles;
using Microsoft.Expression.Encoder;
using System.Collections.ObjectModel;
using System.Windows.Threading;

namespace VideoEncoder
{
    /// <summary>
    /// Interaction logic for VideoProfileControl.xaml
    /// </summary>
    public partial class VideoProfileControl : UserControl
    {
        public ObservableCollection<VideoProfile> VideoProfiles { get; set; }

        private List<VideoModeHelper> videoModes;
        private List<VideoCodecPreset> videCodecPresets;
        private List<VideoComplexity> videoComplexity;

        private MediaItem mediaItem;
        public MediaItem MediaItem
        {
            get { return mediaItem; }
            set
            {
                if (mediaItem != null)
                    mediaItem.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(mediaItem_PropertyChanged);
                mediaItem = value;
                if (mediaItem == null)
                    return;
                SetProfile();
                //widthTextBox.DataContext = mediaItem.VideoSize;
                //heightTextBox.DataContext = mediaItem.VideoSize;
                videoComplexityCombo.SelectedValue = mediaItem.VideoComplexity;
                mediaItem.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(mediaItem_PropertyChanged);
            }
        }

        void mediaItem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Status")
                SetIsEnabled();            
        }
        public VideoProfileControl()
        {
            InitializeComponent();
            videoModes = new List<VideoModeHelper>();
            videoModes.Add(new VideoModeHelper("CBR", VideoMode.Cbr));
            videoModes.Add(new VideoModeHelper("Quality VBR", VideoMode.VbrQuality));
            videoModes.Add(new VideoModeHelper("VBR peak constrained", VideoMode.VbrPeak));
            videoModes.Add(new VideoModeHelper("VBR peak unconstrained", VideoMode.VbrPeakUnconstrained));

            videCodecPresets = new List<VideoCodecPreset>();
            videCodecPresets.Add(VideoCodecPreset.Custom);
            videCodecPresets.Add(VideoCodecPreset.Fast);
            videCodecPresets.Add(VideoCodecPreset.Good);
            videCodecPresets.Add(VideoCodecPreset.Better);
            videCodecPresets.Add(VideoCodecPreset.Best);

            videoComplexity = new List<VideoComplexity>();
            videoComplexity.Add(VideoComplexity.Fastest);
            videoComplexity.Add(VideoComplexity.Fast);
            videoComplexity.Add(VideoComplexity.Good);
            videoComplexity.Add(VideoComplexity.Normal);
            videoComplexity.Add(VideoComplexity.Better);
            videoComplexity.Add(VideoComplexity.Best);

            codecPresetsCombo.ItemsSource = videCodecPresets;
            codecPresetsCombo.SelectionChanged += new SelectionChangedEventHandler(codecPresetsCombo_SelectionChanged);

            modeCombo.ItemsSource = videoModes;
            modeCombo.SelectionChanged += new SelectionChangedEventHandler(modeCombo_SelectionChanged);

            videoComplexityCombo.ItemsSource = videoComplexity;
            videoComplexityCombo.SelectionChanged += new SelectionChangedEventHandler(videoComplexityCombo_SelectionChanged);

            Loaded += new RoutedEventHandler(VideoProfileControl_Loaded);

        }

        void videoComplexityCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (videoComplexityCombo.SelectedIndex == -1)
                return;
            mediaItem.VideoComplexity = videoComplexity[videoComplexityCombo.SelectedIndex];
        }

        void codecPresetsCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (codecPresetsCombo.SelectedIndex == -1)
                return;
            VideoComplexity vComp = mediaItem.VideoComplexity;
            mediaItem.VideoProfile.VideoCodecPreset = videCodecPresets[codecPresetsCombo.SelectedIndex];
            mediaItem.VideoComplexity = vComp;
        }

        void VideoProfileControl_Loaded(object sender, RoutedEventArgs e)
        {
            videoProfileCombo.ItemsSource = VideoProfiles;
            videoProfileCombo.SelectionChanged += new SelectionChangedEventHandler(videoProfileCombo_SelectionChanged);
        }

        void videoProfileCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (videoProfileCombo.SelectedIndex == -1)
                return;
            VideoProfile vProfile = VideoProfiles[videoProfileCombo.SelectedIndex];

            mediaItem.VideoProfile = vProfile;
            SetProfile();
            //videoProfileCombo.SelectedIndex = -1;
        }

        private void SetProfile()
        {
            DataContext = mediaItem.VideoProfile;
            var mode = videoModes.SingleOrDefault(k => k.VideoMode == mediaItem.VideoProfile.Mode);
            modeCombo.SelectedValue = mode;
            codecPresetsCombo.SelectedValue = mediaItem.VideoProfile.VideoCodecPreset;

            SetIsEnabled();
        }

        private void SetIsEnabled()
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate()
            {
                var selectedProfile = VideoProfiles.SingleOrDefault(p => p == mediaItem.VideoProfile);
                videoProfileCombo.SelectedValue = selectedProfile;
                if (mediaItem.Status == ItemStatus.Encoding)
                {
                    videoProfileCombo.IsEnabled = keyframespacing.IsEnabled = modeCombo.IsEnabled = bufferWindowTextBox.IsEnabled =
                        bitrateTextBox.IsEnabled = peakBitrateTextBox.IsEnabled = qualitySlider.IsEnabled = codecPresetsCombo.IsEnabled =
                        videoComplexityCombo.IsEnabled = widthTextBox.IsEnabled = heightTextBox.IsEnabled = false;
                }
                else
                {
                    videoProfileCombo.IsEnabled = keyframespacing.IsEnabled = modeCombo.IsEnabled = bufferWindowTextBox.IsEnabled =
                        bitrateTextBox.IsEnabled = peakBitrateTextBox.IsEnabled = qualitySlider.IsEnabled = codecPresetsCombo.IsEnabled =
                        videoComplexityCombo.IsEnabled = widthTextBox.IsEnabled = heightTextBox.IsEnabled = true;
                }
            });
        }

        void modeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (modeCombo.SelectedIndex == -1)
                return;
            VideoModeHelper helper = videoModes[modeCombo.SelectedIndex];

            mediaItem.VideoProfile.Mode = helper.VideoMode;
            

            bufferWindowTextBlock.Visibility = Visibility.Collapsed;
            bufferWindowTextBox.Visibility = Visibility.Collapsed;
            bufferWindowSecondsTextBlock.Visibility = Visibility.Collapsed;

            bitrateTextBlock.Visibility = Visibility.Collapsed;
            bitrateTextBox.Visibility = Visibility.Collapsed;
            bitrateDescTextBlock.Visibility = Visibility.Collapsed;

            peakBitrateTextBlock.Visibility = Visibility.Collapsed;
            peakBitrateTextBox.Visibility = Visibility.Collapsed;
            peakBitrateDescTextBlock.Visibility = Visibility.Collapsed;

            qualityTextBlock.Visibility = Visibility.Collapsed;
            qualitySlider.Visibility = Visibility.Collapsed;
            qualityTextBox.Visibility = Visibility.Collapsed;


            switch (helper.VideoMode)
            {
                case VideoMode.Cbr:
                    bufferWindowTextBlock.Text = "Buffer window";
                    bufferWindowTextBlock.Visibility = Visibility.Visible;
                    bufferWindowTextBox.Visibility = Visibility.Visible;
                    bufferWindowSecondsTextBlock.Visibility = Visibility.Visible;

                    bitrateTextBlock.Text = "Bitrate";
                    bitrateTextBlock.Visibility = Visibility.Visible;
                    bitrateTextBox.Visibility = Visibility.Visible;
                    bitrateDescTextBlock.Visibility = Visibility.Visible;
                    break;
                case VideoMode.VbrPeak:
                    bufferWindowTextBlock.Text = "Peak buffer window";
                    bufferWindowTextBlock.Visibility = Visibility.Visible;
                    bufferWindowTextBox.Visibility = Visibility.Visible;
                    bufferWindowSecondsTextBlock.Visibility = Visibility.Visible;

                    bitrateTextBlock.Text = "Bitrate(average)";
                    bitrateTextBlock.Visibility = Visibility.Visible;
                    bitrateTextBox.Visibility = Visibility.Visible;
                    bitrateDescTextBlock.Visibility = Visibility.Visible;

                    peakBitrateTextBlock.Visibility = Visibility.Visible;
                    peakBitrateTextBox.Visibility = Visibility.Visible;
                    peakBitrateDescTextBlock.Visibility = Visibility.Visible;
                    break;
                case VideoMode.VbrPeakUnconstrained:
                    bitrateTextBlock.Text = "Bitrate(average)";
                    bitrateTextBlock.Visibility = Visibility.Visible;
                    bitrateTextBox.Visibility = Visibility.Visible;
                    bitrateDescTextBlock.Visibility = Visibility.Visible;
                    break;
                case VideoMode.VbrQuality:
                    qualityTextBlock.Visibility = Visibility.Visible;
                    qualitySlider.Visibility = Visibility.Visible;
                    qualityTextBox.Visibility = Visibility.Visible;
                    break;
                default:
                    break;
            }
        }


    }
}
